package org.apache.ocean;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.ocean.snapshot.Snapshot;
import org.jdom.Element;

public class ShardInfo implements CElement {
	public TransactionID highestTransactionIDDatabase;
	public String id;
	public String status;
	public Map<String,Index> indices = new HashMap<String,Index>();
	
	public ShardInfo() {}
	
	public String toString() {
		return ReflectionToStringBuilder.toString(this);
	}
	
	public void add(Index index) {
		indices.put(index.id, index);
	}
	
	public void addAll(List<Index> list) {
		for (Index index : list) {
		  indices.put(index.id, index);
		}
	}
	
	public static class Index implements CElement, Changed<String,Index> {
		public static final String RAM = "ram";
		public static final String DISK = "disk";
		public static final String CURRENT = "current";
		public static final String FINISHED = "finished";
		public String type;
		public String id;
		public CLong segmentsVersion;
		public String status;
		public Snapshot snapshot;
		//public Map<String,IndexFile> files = new HashMap<String,IndexFile>();
		
		public String getKey() {
			return id;
		}
		
		public boolean stillSame(Index other) {
			EqualsBuilder equalsBuilder = new EqualsBuilder();
			//equalsBuilder.append(files, other.files);
			return equalsBuilder.isEquals();
		}
		
		public Index() {}
		
		public Index(Element element) throws Exception {
			id = XMLUtil.getAttributeString("id", element);
			type = XMLUtil.getAttributeString("type", element);
			status = XMLUtil.getAttributeString("status", element);
			segmentsVersion = XMLUtil.getAttributeLong("segmentsVersion", element);
			Element snapshotElement = element.getChild("snapshot");
			if (snapshotElement != null) {
				snapshot = new Snapshot(snapshotElement);
			}
		}
		
		public Element toElement() throws Exception {
			Element element = new Element("index");
			XMLUtil.setAttribute("segmentsVersion", segmentsVersion, element);
			XMLUtil.setAttribute("type", type, element);
			XMLUtil.setAttribute("status", status, element);
			XMLUtil.setAttribute("id", id, element);
			if (snapshot != null) element.addContent(snapshot.toElement());
			//for (IndexFile indexFile : files.values()) {
			//	element.addContent(indexFile.toElement());
			//}
			return element;
		}
		
		//public void addAll(List<IndexFile> indexFiles) {
		//	for (IndexFile indexFile : indexFiles) {
		//		files.put(indexFile.name, indexFile);
		//	}
		//}
		
		public static class IndexFile implements CElement, Changed<String,IndexFile> {
			public CLong lastModified;
			public String name;
			public CLong size;
			
			public String getKey() {
				return name;
			}
			
			public boolean stillSame(IndexFile other) {
				return EqualsBuilder.reflectionEquals(this, other);
			}
			
			public IndexFile() {}
			
			public IndexFile(Element root) throws Exception {
				XMLUtil.reflectToObject(this, root);
			}
			
			public Element toElement() throws Exception {
				return XMLUtil.reflectToElement("indexfile", this);
			}
		}
		
		//public void add(IndexFile file) {
		//	files.put(file.name, file);
		//}
	}
	
  public ShardInfo(Element element) throws Exception {
  	id = XMLUtil.getChildText("id", element);
  	status = XMLUtil.getChildText("status", element);
  	highestTransactionIDDatabase = TransactionID.parse(XMLUtil.getChildText("highestTransactionIDDatabase", element));
  	for (Element indexElement : XMLUtil.getChildren("index", element)) {
  		add(new Index(indexElement));
  	}
  }
  
  public Element toElement() throws Exception {
  	Element element = new Element("shardinfo");
  	XMLUtil.createTextElement("id", id, element);
  	XMLUtil.createTextElement("status", status, element);
  	XMLUtil.createTextElement("highestTransactionIDDatabase", highestTransactionIDDatabase, element);
  	for (Index index : indices.values()) {
  		element.addContent(index.toElement());
  	}
  	return element;
  }
}
